﻿using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;

namespace WoodRobotics.Weather.ModelView
{
    
    public class IPtoGeo
    {
        
        #region Constructor
        public IPtoGeo()
        {
            XMLNameSpace = "http://data.quova.com/1";
            Service = "http://api.quova.com/";
            Version = "v1/";
            Method = "ipinfo/";
            APIKey = "100.zt74esxwh9ygjypwhuey";
            Secret = "9sZ7QjEj";
        }
        #endregion
        
        #region Fields
        private string m_MD5Hash;
        private string m_APIKey;
        private string m_Secret;
        private AsyncCallback m_Target;
        #endregion
        
        #region Properties
        public ORM.ipinfo GeoInfo { get; set; }
        public string XMLNameSpace { get; set; }
        public string Service { get; set; }
        public string Version { get; set; }
        public string Method { get; set; }
        public string IpAddress { get; set; }
        public string APIKey
        {
            get { return m_APIKey; }
            set
            {
                m_APIKey = value;
                MD5GenerateHash();
            }
        }
        public string Secret
        {
            get { return m_Secret; }
            set
            {
                m_Secret = value;
                MD5GenerateHash();
            }
        }
        #endregion
        
        #region Events
        private void GeoResponse(IAsyncResult Responce)
        {
            
            try
            {
                
                HttpWebRequest l_WebRequest = (HttpWebRequest)Responce.AsyncState;
                HttpWebResponse l_WebResponce = (HttpWebResponse)l_WebRequest.EndGetResponse(Responce);
                
                GeoInfo = (ORM.ipinfo)new XmlSerializer(typeof(ORM.ipinfo), XMLNameSpace).Deserialize(new StreamReader(l_WebResponce.GetResponseStream()));
                
                m_Target.Invoke(null);
                
            }
            catch 
            {
            }
            
        }
        #endregion
        
        #region Methods
        public void BeginQueryGeoIP(AsyncCallback Target)
        {
            
            if (Service != "" &&
                Version != "" &&
                Method != "" &&
                IpAddress != "" &&
                APIKey != "" &&
                Secret != "" &&
                m_MD5Hash != "")
            {
                
                m_Target = Target;
                
                string l_URL = Service + Version + Method + IpAddress + "?apikey=" + APIKey + "&sig=" + m_MD5Hash;
                
                HttpWebRequest l_WebRequest = WebRequest.Create(l_URL) as HttpWebRequest;
                l_WebRequest.BeginGetResponse(new AsyncCallback(GeoResponse), l_WebRequest);
                
            }
            
        } 
        private void MD5GenerateHash()
        {
            
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 l_MD5Hasher = MD5.Create();
            
            // Convert the input string to a byte array and compute the hash.
            byte[] l_MD5Data = l_MD5Hasher.ComputeHash(Encoding.Default.GetBytes(APIKey + Secret + (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds));
            
            // Create a new String builder to collect the bytes and create a string.
            StringBuilder l_SBuilder = new StringBuilder();
            
            // Loop through each byte of the hashed data and format each one as a hexadecimal string.
            for (int nIndex = 0; nIndex < l_MD5Data.Length; ++nIndex)
                l_SBuilder.Append(l_MD5Data[nIndex].ToString("x2"));
            
            // Return the hexadecimal string.
            m_MD5Hash = l_SBuilder.ToString();
            
        }
        #endregion
        
    }
    
}